package com.qianniu.napi.admin.web.login;

import akka.actor.ActorRef;
import akka.actor.Props;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.google.common.base.Strings;
import com.qianniu.napi.admin.entity.*;
import com.qianniu.napi.admin.entity.penum.Qgettype;
import com.qianniu.napi.admin.entity.wxbean.WeChat;
import com.qianniu.napi.admin.service.*;
import com.qianniu.napi.admin.service.akka.AkkaServer;
import com.qianniu.napi.admin.service.akka.FanActor;
import com.qianniu.napi.admin.service.akka.UserActor;
import com.qianniu.napi.common.config.Constants;
import com.qianniu.napi.common.util.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.BufferedOutputStream;
import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * Created by chenxuebin on 2017/8/9.
 */
@RestController
public class WeixinController {

    @Autowired
    private ICouponService couponService;
    @Autowired
    private ICouponTplService couponTplService;

    @Autowired
    private IUserService userService;
    @Autowired
    private IRedisService redisService;
    @Autowired
    private IAccountService accountService;

    @Autowired
    private IMconfigExtService mconfigExtService;
    @Autowired
    private IMerchantConfigService merchantConfigService;
    @Autowired
    private IWeixinService weixinService;

    private static final Logger logger = LoggerFactory.getLogger(WeixinController.class);

    @RequestMapping("/test")
    @ResponseBody
    public JsonDO test() {

        JsonDO json = new JsonDO();
        json.setData("success");
        return json;
    }

    @RequestMapping(value = "/api/user/login", method = RequestMethod.POST)
    @ResponseBody
    public Map wxapplogin(@RequestParam("encryptedData") String encryptedData,
                          @RequestParam("iv") String iv,
                          @RequestParam("code") String code,
                          @RequestParam(value = "ismember", required = false) Integer ismember,
                          @RequestParam(value = "g", required = false) String guid,
                          @RequestParam(value = "s", required = false) String s,
                          @RequestParam(value = "ud", required = false) String ud,
                          @RequestParam(value = "ori", required = false) String ori
    ) throws Exception {
        //初始化配置文件
        logger.warn("=====================api/user/login start=====================");

        Map map = new HashMap<String, Object>();
        logger.warn("----------------guid=" + guid);
        logger.warn("----------------s=" + s);
        logger.warn("----------------ud=" + ud);
        logger.warn("----------------ori=" + ori);
        logger.warn("------------------------------------------------params encryptedData=" + encryptedData);
        logger.warn("------------------------------------------------params iv=" + iv);
        logger.warn("------------------------------------------------params code=" + code);
        encryptedData = encryptedData.replaceAll(" ", "+");
        logger.debug("---------------------wxapplogin after replaceAll encryptedData::" + encryptedData);

        //登录凭证不能为空
        if (code == null || code.length() == 0) {
            map.put("status", 1);
            map.put("msg", "code 不能为空");
            return map;
        }
        Long mid = ObjectUtil.getMid();
        String appid = ObjectUtil.getAppid();
        if (mid == null || mid <= 0) {
            map.put("code", 1);
            map.put("msg", "paramter error");
            return map;
        }

        // add redis cache
        MerchantApp mApp = redisService.getMApp();

        logger.info("======user/login mApp=" + mApp);
        if (mApp == null) {
            map.put("code", 2);
            map.put("msg", "未找到商家应用配置");
            return map;
        }

        if (Strings.isNullOrEmpty(mApp.getAppid())) {
            map.put("code", 2);
            map.put("msg", "商家应用还未初始化配置");
            return map;
        }

        // mApp.getAppid() 为非(多门店多分店）商家默认的appid 只有一个
        // ObjectUtil.getAppid() 为多门店多分点商家对应其中某一个的appid
        appid = mApp.getAppid();
        Long mpid = ObjectUtil.getMpid();
        String secret = mApp.getAppsecret();

        map.clear();

        //////////////// 2、对encryptedData加密数据进行AES解密 ////////////////
        try {
            String grant_type = "authorization_code";
            String rskey = Constants.REDIS_SESSION_KEY + mpid + "_" + ObjectUtil.getGuid();
            logger.warn("--------------------------------------wxdectypt rskey=" + rskey);
            String rsessionKey = redisService.get(rskey);
            String sessionKey = rsessionKey;
            String openid = "";
            // 默认使用当前服务器缓存的sessionKey
            if (Strings.isNullOrEmpty(rsessionKey)) {
                //////////////// 1、向微信服务器 使用登录凭证 code 获取 session_key 和 openid ////////////////
                //请求参数
                MerchantApp mapp = redisService.getMApp(mpid);
                String params = "appid=" + mapp.getAppid() + "&secret=" + mapp.getAppsecret() + "&js_code=" + code + "&grant_type=" + grant_type;
                logger.info("-------------------------params=" + params);
                //发送请求
                String sr = HttpUtil.sendGet(Constants.WX_URL_JSCODE2SESSION, params);
                logger.debug("-------------------------sr=" + sr);
                //解析相应内容（转换成json对象）
                JSONObject json = JSONObject.parseObject(sr);
                //获取会话密钥（session_key）
                if (json == null || Strings.isNullOrEmpty(json.getString("session_key"))) {
                    logger.debug("sessionKey error for params=" + params);
                    map.put("code", 4);
                    map.put("status", 0);
                    map.put("msg", "解密失败");
                    return map;
                }
                sessionKey = json.getString("session_key");
                openid = json.getString("openid");
                logger.warn("------------------------------------------------sessionKey from http=" + sessionKey);
            } else {
                logger.warn("------------------------------------------------sessionKey from redis=" + sessionKey);
            }
            //如果缓存为空
            if (Strings.isNullOrEmpty(rsessionKey)) redisService.set(rskey, sessionKey, 7200, TimeUnit.SECONDS);

            String result = AesUtil.decrypt(encryptedData, sessionKey, iv, rskey);
            logger.warn("------------------------------------------------AesUtil.decrypt result=" + sessionKey);
//            JSONObject userInfoJSON = ObjectUtil.wxdectypt(encryptedData, iv, code,map,true);
            JSONObject userInfoJSON = JSON.parseObject(result);
            if (null != userInfoJSON) {
                map.put("code", 0);
                map.put("msg", "ok");

//                JSONObject userInfoJSON = JSONObject.parseObject(result);
                Map userInfo = new HashMap();

                String ip = ObjectUtil.getIP();
//                String location = ObjectUtil.getLocation();
                logger.debug("======ip=" + ip);

                userInfo.put("openId", Strings.isNullOrEmpty(openid)?userInfoJSON.get("openId"):openid);
                userInfo.put("nickName", userInfoJSON.get("nickName"));
                userInfo.put("avatarUrl", userInfoJSON.get("avatarUrl"));
                userInfo.put("gender", userInfoJSON.get("gender"));
                userInfo.put("city", userInfoJSON.get("city"));
                userInfo.put("province", userInfoJSON.get("province"));
                userInfo.put("country", userInfoJSON.get("country"));
                userInfo.put("unionId", userInfoJSON.get("unionId"));
                userInfo.put("appid", appid);
                userInfo.put("appType", ObjectUtil.getAppType());
                userInfo.put("ip", ip);

                if (!Strings.isNullOrEmpty(guid)) userInfo.put("guid", guid);
                if (!Strings.isNullOrEmpty(ud)) userInfo.put("ud", ud);
                userInfo.put("mid", mid);
                userInfo.put("mpid", mpid);
                if (mApp.getAsmpid() != null && mApp.getVersion().intValue() == 9) {
                    logger.debug("-------------------------------------------------------------mApp.getAsmpid()=" + mApp.getAsmpid());
                    logger.debug("-------------------------------------------------------------mApp.getVersion().intValue()=" + mApp.getVersion().intValue());
                    userInfo.put("asmpid", mApp.getAsmpid());
                }

                if (!Strings.isNullOrEmpty(ori)) userInfo.put("ori", ori);
                if (!Strings.isNullOrEmpty(s)) userInfo.put("scene", s);

                logger.debug(">>>userInfo=" + userInfo);
                User user = updateUserinfo(userInfo);
                logger.debug(">>>user after updateUserinfo user=" + user);

                if (userInfo.containsKey("updateGuid")) {
                    logger.debug("------------------------------process updateGuid");
                    String rsnewkey = Constants.REDIS_SESSION_KEY + mpid + "_" + user.getGuid();
                    redisService.set(rsnewkey, sessionKey, 7200, TimeUnit.SECONDS);
                    redisService.set(rskey, sessionKey, 7200 - 200, TimeUnit.SECONDS);// 旧缓存默认值，设置过期清除
                }

                logger.debug(">>>ObjectUtil.getMpid()=" + ObjectUtil.getMpid());
                logger.debug(">>>user.isIsnew()=" + user.getNewuser());

                if (mpid == 2 && user.getNewuser()) {
                    logger.debug(">>>ready to tell akka msg");
                    // 名片,异步创建用户统计信息
                    AkkaServer.system.actorOf(Props.create(UserActor.class))
                            .tell(Constants.AKKA_MSG_CUSERSTAT + "@" + user.getId(), ActorRef.noSender());
                }

                logger.debug(">>>ready to tell akka AKKA_USER_CREATE_AVATOR");
                // 头像,异步创建用户统计信息
                AkkaServer.system.actorOf(Props.create(UserActor.class))
                        .tell(Constants.AKKA_USER_CREATE_AVATOR + "@" + user.getId(), ActorRef.noSender());

                userInfo.remove("unionId");

                String key = ObjectUtil.getKey(user);
                String token = AesUtil.encrypt(key, Constants.ENCODE_KEY);
                redisService.set(token, key);

                //处理分销
                logger.debug("----------------------------------------------------------------------------before start to record fenxiao user=" + JSON.toJSONString(user));
                //推荐新用户
                if (user.getNewuser() != null && user.getNewuser()) {
                    logger.debug("------------------------------------------------------wxapplogin start to record fenxiao");
                    logger.debug("---------------------------------------------s=" + s);
                    logger.debug("---------------------------------------------ori=" + ori);

                    // 自己注册奖励
                    AkkaServer.system.actorOf(Props.create(FanActor.class))
                            .tell(Constants.AKKA_MSG_REGIST + "@" + user.getId() + "@" + user.getMpid(), ActorRef.noSender());

                    // 自己注册分销奖励(奖励上一级用户)
                    if (!Strings.isNullOrEmpty(s)) AkkaServer.system.actorOf(Props.create(UserActor.class))
                            .tell(Constants.AKKA_MSG_FENXIAO_SCENE + "@" + s + "@" + user.getId(), ActorRef.noSender());
                    else if (!Strings.isNullOrEmpty(ori)) AkkaServer.system.actorOf(Props.create(UserActor.class))
                            .tell(Constants.AKKA_MSG_FENXIAO_ORI + "@" + ori + "@" + user.getId(), ActorRef.noSender());

                }

                map.put("guid", user.getGuid());
                map.put("ismch", user.getIsMch());
                map.put("islogin", 1);
                map.put("token", token);
                //获取登陆用户会员级别
                if (ismember != null && ismember == 1) {
                    map.put("mlevel", user.getIsMember() == 1 ? user.getMemberLevel() : 0);
                }

                return map;
            }
        } catch (Exception e) {
            logger.error("==========encryptedData and process user data error", e);
        }
        map.put("code", 4);
        map.put("status", 0);
        map.put("msg", "解密失败");
        return map;
    }

    @RequestMapping(value = "/api/user/lanuch")
    @ResponseBody
    public Map lanuch(@RequestParam("t") String t,
                      @RequestParam(value = "ismember", required = false) Integer ismember,
                      @RequestParam("g") String guid) throws Exception {
        //初始化配置文件
        Map map = new HashMap<String, Object>();
        logger.info("========t=" + t);
        User user = redisService.getUser();
        // 登陆用户添加商户ID
        if (user != null && user.getSid() != null && user.getSid() > 0
                && ObjectUtil.getSid() == null) {
            redisService.del(t);
            MerchantApp mApp = redisService.getMApp();
            String key = mApp.getMid() + "__" + mApp.getId() + "__" + user.getId().toString() + "__" + ObjectUtil.randomStrings(8, 1).get(0) + "__" + mApp.getAppid() + "__" + mApp.getAppType() + "__" + user.getSid();
            String token = AesUtil.encrypt(key, Constants.ENCODE_KEY);
            redisService.set(token, key);
            map.put("token", token);
            map.put("islogin", 1);
        }

        //未登陆用户
        //User guser = redisService.getUserByGuid(guid);
        User guser = null;
        logger.info("----------------------------------------------------------user/lanuch guser=" + guser);
        logger.info("----------------------------------------------------------user/lanuch ObjectUtil.getUid()=" + ObjectUtil.getUid());
        if (guser == null) {
            map.put("isnew", "1");
            map.put("islogin", 0);
        } else if (guser != null && ObjectUtil.getUid() == null) {
//          int cnt = couponService.selectCount(new EntityWrapper<Coupon>().eq("uid", ObjectUtil.getUid()));
            int cnt = 0;
            if (cnt == 0) map.put("isnew", "1");
            map.put("islogin", 1);
            redisService.del(t);
            MerchantApp mApp = redisService.getMApp();
            String key = mApp.getMid() + "__" + mApp.getId() + "__" + user.getId().toString() + "__" + ObjectUtil.randomStrings(8, 1).get(0) + "__" + mApp.getAppid() + "__" + mApp.getAppType() + "__";
            String token = AesUtil.encrypt(key, Constants.ENCODE_KEY);
            redisService.set(token, key);
            map.put("token", token);
        }
        if (user != null && ismember != null && ismember == 1) {
            map.put("mlevel", user.getIsMember() == 1 ? user.getMemberLevel() : 0);
        }
        if (user != null && !Strings.isNullOrEmpty(guid) && !guid.equals(user.getGuid())) {
            map.put("guid", user.getGuid());
        }
        logger.info("-----------------------------------------------------------user/lanuch map=" + map);
        return map;
    }

    //非匿名绑定手机（登陆状态绑定手机）
    @RequestMapping(value = "/api/user/jiemiwx", method = RequestMethod.POST)
    @ResponseBody
    public Jinfo jiemiwx(@RequestParam("encryptedData") String encryptedData,
                         @RequestParam("iv") String iv,
                         @RequestParam(value = "act", required = false) Integer act,
                         @RequestParam(value = "g", required = false) String guid,
                         @RequestParam(value = "utype", required = false) Integer utype,
                         @RequestParam(value = "level", required = false) Integer level,
                         @RequestParam("code") String code,
                         @RequestParam("t") String t
    ) throws Exception {
        //初始化配置文件
        Jinfo info = new Jinfo();
        logger.info("========================================params encryptedData::" + encryptedData);
        logger.info("========================================params iv=" + iv);
        logger.info("========================================params code=" + code);
        encryptedData = encryptedData.replaceAll(" ", "+");
        logger.debug("--------------------------------------------jiemiwx after replaceAll encryptedData::" + encryptedData);

        //登录凭证不能为空
        if (code == null || code.length() == 0) {
            info.setCode(1);
            info.setMsg("paramter error");
            return info;
        }
        Long mid = ObjectUtil.getMid();
        String rkey = Constants.REDIS_APP + mid + "_" + ObjectUtil.getAppid();
        logger.info("===============rkey=" + rkey);

        MerchantApp mApp = redisService.getMApp();

        String appid = ObjectUtil.getAppid();
        Long mpid = ObjectUtil.getMpid();
        String secret = mApp.getAppsecret();

        logger.info("===============secret=" + secret);
        //授权（必填）
        String grant_type = "authorization_code";
        String rskey = Constants.REDIS_SESSION_KEY + mpid + "_" + ObjectUtil.getGuid();
        String rsessionKey = redisService.get(rskey);
        String sessionKey = rsessionKey;
        String unionid = null;
        if (Strings.isNullOrEmpty(rsessionKey)) {
            //////////////// 1、向微信服务器 使用登录凭证 code 获取 session_key 和 openid ////////////////
            String params = "appid=" + appid + "&secret=" + secret + "&js_code=" + code + "&grant_type=" + grant_type;
            logger.info("===============params=" + params);
            //发送请求
            String sr = HttpUtil.sendGet(Constants.WX_URL_JSCODE2SESSION, params);
            logger.debug(">>>>>>>>>>>>>>>>>>>>>>>sr=" + sr);
            //解析相应内容（转换成json对象）
            JSONObject json = JSONObject.parseObject(sr);
            //获取会话密钥（session_key）
            sessionKey = json.get("session_key").toString();
            if (json.containsKey("unionid")) unionid = json.get("unionid").toString();
            if (Strings.isNullOrEmpty(sessionKey)) {
                info.setCode(1);
                info.setMsg("sessionKey error");
                return info;
            }
        }
        if (Strings.isNullOrEmpty(rsessionKey)) {
            redisService.set(rskey, sessionKey, 7200, TimeUnit.SECONDS);
        }

        //用户的唯一标识（openid）
//        String openid = (String) json.get("openid");
        logger.info("===============session_key=" + sessionKey);

        //////////////// 2、对encryptedData加密数据进行AES解密 ////////////////
        try {
            String result = AesUtil.decrypt(encryptedData, sessionKey, iv, rskey);

            if (null != result && result.length() > 0) {
                logger.info("===============result=" + result);
                JSONObject jo = JSONObject.parseObject(result);

                boolean firstbindPhone = false;
                if (ObjectUtil.getUid() != null) {
                    User curuser = userService.selectById(ObjectUtil.getUid());
                    Account account = accountService.selectOne(new EntityWrapper<Account>().eq("uid", ObjectUtil.getUid()));
                    if (account != null) {
                        account.setPhone(curuser.getPhone());
                        account.setHeadimg(curuser.getAvatarPic());
                        account.setNickname(curuser.getNickName());
                        account.updateById();
                    }

                    if (curuser != null && (curuser.getPhone() == null || curuser.getPhone().equals("")))
                        firstbindPhone = true;
                }

                User nuser = new User();

                // 一个老板可能多个商家##待改进
//                User muser = userService.selectOne(new EntityWrapper<User>().eq("phone", jo.getString("phoneNumber"))
//                        .eq("is_platform", 1)
//                        .eq("is_admin", 1)
//                        .ne("apptype", 9));
                List<User> musers = userService.getMuser(jo.getString("phoneNumber"), null);
                User muser = null;
                if (musers != null && musers.size() > 0) muser = musers.get(0);
                logger.info("------------------------------------------------------muser=" + JSON.toJSONString(muser));
                if (jo.containsKey("phoneNumber") && (ObjectUtil.getUid() != null || !Strings.isNullOrEmpty(guid))) {

                    if (ObjectUtil.getUid() != null) nuser.setId(ObjectUtil.getUid());
                    if (!Strings.isNullOrEmpty(guid)) nuser.setGuid(guid);
                    if (!Strings.isNullOrEmpty(unionid)) nuser.setUnionid(unionid);

                    nuser.setPhone(jo.getString("phoneNumber"));
                    // ------------------ 设置关联小程序 ----------------
                    if (act != null && act == 1) nuser.setAsmpid(muser == null ? null : muser.getMpid());
                    // 此处适配时代口腔 绑定手机号默认成为会员
                    if (utype != null && utype.intValue() > 0 && level != null) {
                        nuser.setUtype(utype);
                        if (utype == 1) {
                            nuser.setIsMember(1);
                            nuser.setMemberLevel(level);
                        }
                    }
                    // ------------------end 设置关联小程序 end-------------
                    if (ObjectUtil.getUid() != null) nuser.insertOrUpdate();
                    else {
                        userService.update(nuser, new EntityWrapper<User>().eq("guid", guid));
                    }
                    logger.info("------------------------------------------------ObjectUtil.getUid()=" + ObjectUtil.getUid());
                    logger.info("------------------------------------------------guid=" + guid);

                    // 判断第一次邦手机，通知积分奖励
                    if (firstbindPhone) {
                        AkkaServer.system.actorOf(Props.create(FanActor.class))
                                .tell(Constants.AKKA_MSG_BIND_PHONE + "@" + ObjectUtil.getUid() + "@" + mpid, ActorRef.noSender());
                    }
                }

                // 更新用户缓存信息
                redisService.delUser();

                if (muser != null && jo.containsKey("phoneNumber") && act != null && act == 1) {
                    String key = ObjectUtil.getKey(muser);
                    String token = AesUtil.encrypt(key, Constants.ENCODE_KEY);
                    redisService.del(t);
                    redisService.set(token, key);
                    logger.info("========jiemiwx token=" + token);
                    logger.info("========jiemiwx key=" + key);
                    info.setToken(token);
                }

                info.setInfo(jo);
                return info;
            } else {
                info.setCode(1);
                info.setMsg("parse and decrypt error");
            }
        } catch (Exception e) {
            logger.error("======jiemiwx error", e);
            info.setCode(1);
        }

        return info;
    }

    //匿名绑定手机（非登陆状态绑定手机）
    @RequestMapping(value = "/api/user/bindphone", method = RequestMethod.POST)
    @ResponseBody
    public Jinfo bindphone(
            @RequestParam("encryptedData") String encryptedData,
            @RequestParam("iv") String iv,
            @RequestParam(value = "v", required = false) Integer version,
            @RequestParam(value = "act", required = false) Integer act,
            @RequestParam(value = "g", required = false) String guid,
            @RequestParam(value = "ud", required = false) String ud,
            @RequestParam(value = "asmpid", required = false) Long asmpid,
            @RequestParam("code") String code,
            @RequestParam("t") String t
    ) throws Exception {
        //初始化配置文件
        Jinfo info = new Jinfo();
        logger.info("---------------------------------------params encryptedData::" + encryptedData);
        logger.info("---------------------------------------params iv=" + iv);
        logger.info("---------------------------------------params code=" + code);
        logger.info("---------------------------------------params version=" + version);
        encryptedData = encryptedData.replaceAll(" ", "+");
        logger.debug("--------------------------------------bindphone after replaceAll encryptedData::" + encryptedData);

        //登录凭证不能为空
        if (code == null || code.length() == 0) {
            info.setCode(1);
            info.setMsg("paramter error");
            return info;
        }
        Long mid = ObjectUtil.getMid();
        String rkey = Constants.REDIS_APP + mid + "_" + ObjectUtil.getAppid();
        logger.info("===============rkey=" + rkey);

        MerchantApp mApp = redisService.getMApp();

        String appid = ObjectUtil.getAppid();
        Long mpid = ObjectUtil.getMpid();
        String secret = mApp.getAppsecret();

        logger.info("===============secret=" + secret);
        //授权（必填）
        String grant_type = "authorization_code";
        String rskey = Constants.REDIS_SESSION_KEY + mpid + "_" + ObjectUtil.getGuid();
        String rsessionKey = redisService.get(rskey);
        String sessionKey = rsessionKey;
        if (Strings.isNullOrEmpty(rsessionKey)) {
            //1、向微信服务器 使用登录凭证 code 获取 session_key 和 openid
            String params = "appid=" + appid + "&secret=" + secret + "&js_code=" + code + "&grant_type=" + grant_type;
            logger.info("--------------------params=" + params);
            //发送请求
            String sr = HttpUtil.sendGet(Constants.WX_URL_JSCODE2SESSION, params);
            logger.debug("--------------------sr=" + sr);
            //解析相应内容（转换成json对象）
            JSONObject json = JSONObject.parseObject(sr);
            //获取会话密钥（session_key）
            sessionKey = json.get("session_key").toString();
            if (Strings.isNullOrEmpty(sessionKey)) {
                info.setCode(1);
                info.setMsg("sessionKey error");
                return info;
            }
        }
        if (Strings.isNullOrEmpty(rsessionKey)) {
            redisService.set(rskey, sessionKey, 7200, TimeUnit.SECONDS);
        }

        //用户的唯一标识（openid）
//        String openid = (String) json.get("openid");
        logger.info("--------------------session_key=" + sessionKey);

        //////////////// 2、对encryptedData加密数据进行AES解密 ////////////////
        try {
            String result = AesUtil.decrypt(encryptedData, sessionKey, iv, rskey);

            if (null != result && result.length() > 0) {
                logger.info("--------------------result=" + result);
                JSONObject jo = JSONObject.parseObject(result);
                //非登录
                User curuser = userService.selectOne(new EntityWrapper<User>().eq("mpid", ObjectUtil.getMpid())
                        .eq("phone", jo.getString("phoneNumber")));
                if (curuser == null) {
                    curuser = new User();
                    curuser.setGuid(guid);
                    curuser.setPhone(jo.getString("phoneNumber"));
                    curuser.setMid(ObjectUtil.getMid());
                    curuser.setMpid(ObjectUtil.getMpid());
                    curuser.setUd(ud);
                    curuser.setCreatetime(new Date());
                    curuser.insert();
                }
                redisService.delUserByguid(guid);

//                User nuser = new User();
                //如果要求登陆商户端，仅限独立版小程序登陆
                if (act != null && act == 1) {
                    //一个老板可能多个商家##待改进
                    List<User> musers = userService.getMuser(jo.getString("phoneNumber"), asmpid);
                    User muser = null;
                    if (musers != null && musers.size() > 0) muser = musers.get(0);
                    logger.info("--------------------------------------muser=" + JSON.toJSONString(muser));

                    if (muser != null && jo.containsKey("phoneNumber")) {
                        String key = ObjectUtil.getKey(muser);
                        String token = AesUtil.encrypt(key, Constants.ENCODE_KEY);
                        redisService.del(t);
                        redisService.set(token, key);
                        info.setToken(token);
                        info.setGuid(muser.getGuid());
                        jo.put("nickName", muser.getNickName());
                        jo.put("avatarPic", muser.getAvatarPic());
                    }
                    if (muser != null && version != null && version > 0) {
                        MconfigExt mconfigExt = mconfigExtService.selectById(muser.getMpid());
                        if (mconfigExt != null) {
                            info.setExtra(version > mconfigExt.getVersion());
                        } else {
                            info.setExtra(false);
                        }
                    }
                }

                info.setInfo(jo);
                return info;
            } else {
                info.setCode(1);
                info.setMsg("绑定手机失败");
            }
        } catch (Exception e) {
            logger.error("======bindphone error", e);
        }

        return info;
    }

    private User updateUserinfo(Map uMap) {
        logger.debug("--------------------updateUserinfo uMap=" + uMap);

        List<User> list = userService.selectList(new EntityWrapper<User>()
                .eq("openid", uMap.get("openId")).orderBy("mpid", false));

        User user = list == null || list.size() == 0 ? null : list.get(0);
        logger.debug(">>>user openid=" + user);
        boolean newguid = false;
        if (user == null) {
            logger.debug(">>>user openid 111");
            user = new User();
            user.setOpenid(uMap.get("openId").toString());
            user.setNickName(uMap.get("nickName").toString());
            user.setAvatarPic(uMap.get("avatarUrl").toString());
            user.setGender(uMap.get("gender").toString());

            user.setCity(uMap.get("city").toString());
            user.setProvince(uMap.get("province").toString());
            user.setCountry(uMap.get("country").toString());
            user.setMid(Long.valueOf(uMap.get("mid").toString()));
            user.setMpid(Long.valueOf(uMap.get("mpid").toString()));

            if (uMap.containsKey("asmpid")) user.setAsmpid(Long.valueOf(uMap.get("asmpid").toString()));
            user.setApptype(Integer.valueOf(uMap.get("appType").toString()));

            user.setIsMember(-1);
            user.setHasmp(0);
            user.setState(1);
            user.setIsMch(-1);
            if (uMap.containsKey("guid"))
                user.setGuid(uMap.get("guid").toString());
            else
                user.setGuid(StringUtil.getGUID());

            while (userService.selectCount(new EntityWrapper<User>().setSqlSelect("id").eq("guid", user.getGuid())) > 0) {
                user.setGuid(StringUtil.getGUID());
                newguid = true;
            }

            if (uMap.containsKey("ud"))
                user.setUd(uMap.get("ud").toString());

            if (uMap.containsKey("ip"))
                user.setIp(uMap.get("ip").toString());

            if (uMap.containsKey("location"))
                user.setLocation(uMap.get("location").toString());

            user.setCreatetime(new Date());
            user.setMid(ObjectUtil.getMid());

            if (uMap.containsKey("unionId") && uMap.get("unionId") != null) {
                user.setUnionid(uMap.get("unionId").toString());
            }

            MerchantConfig mconfig = redisService.getMconfig(user.getMpid());
            user.setMemberLevel(mconfig.getDefaultMemberLevel());
            user.setUtype(1);
            logger.debug("-------------------------------------------------------------insert user=" + JSON.toJSONString(user));

            String oriscene = "";
            String ori = "";
            String scene = "";

            if (uMap.containsKey("scene") && uMap.get("scene") != null
                    && uMap.get("scene").toString().length() > 0
                    && !uMap.get("scene").equals("undefined")) {
                scene = uMap.get("scene").toString();
            }
            logger.debug("-------------------------------------------------------------user openid 000 scene=" + scene);
            if (uMap.containsKey("ori") && uMap.get("ori") != null
                    && uMap.get("ori").toString().length() > 0
                    && !uMap.get("ori").equals("undefined")) {
                ori = uMap.get("ori").toString();
            }
            oriscene = scene + "@" + ori;
            logger.debug("-------------------------------------------------------------user openid 222 ori=" + ori);
            logger.debug("-------------------------------------------------------------user openid 222 oriscene=" + oriscene);

            Long puid = ObjectUtil.orderFanuid(oriscene);
            User puser = puid == null ? null : userService.selectById(puid);
            String genlink = puser == null ? "0" : (puser.getGenlink() == null ? "0#" + puid : puser.getGenlink() + "#" + puid);
            user.setGenlink(genlink);

            user.insert();
            user.setNewuser(true);

            logger.debug(">>>user openid 333");
            // 插入默认账户信息
            MerchantConfig mc = merchantConfigService.selectList(new EntityWrapper<MerchantConfig>().eq("mpid", uMap.get("mpid").toString())).get(0);
            BigDecimal zero = new BigDecimal(0);
            if (mc.getIsMember() == 1) {
                Account act = new Account();
                act.setUid(user.getId());
                act.setNickname(user.getNickName());
                act.setPhone(user.getPhone());
                act.setHeadimg(user.getAvatarPic());

                act.setMid(user.getMid());
                act.setMpid(user.getMpid());
                act.setCreatetime(user.getCreatetime());
                act.setUnionid(user.getUnionid());

                act.setTotal(zero);
                act.setAmount(zero);
                act.setUnuseAmount(zero);
                act.setFanli(zero);
                act.setFanliing(zero);
                act.setFreeze(zero);
                act.setChargeAmount(zero);
                act.setLjxiaofei(zero);
                act.setMamount(zero);
                act.setWithdraw(zero);
                act.insert();
            }
            if (mc.getIsJifen() == 1) {
                Jifen jifen = new Jifen();
                jifen.setState(1);
                jifen.setUid(user.getId());
                jifen.setMid(user.getMid());
                jifen.setMpid(user.getMpid());
                jifen.setCreatetime(user.getCreatetime());
                jifen.setTotal(zero);
                jifen.setFanliing(zero);
                jifen.insert();
            }
        } else {
            // 检查用户字段是否用变更，主要是avatarUrl+nickName检查
            if (user.getGuid() != null && uMap.containsKey("guid") && !user.getGuid().equals(uMap.get("guid").toString())) {
                uMap.put("guid", user.getGuid());
                uMap.put("updateGuid", true);
            }
            user.setNickName(uMap.get("nickName").toString());
            user.setAvatarPic(uMap.get("avatarUrl").toString());
            user.setGender(uMap.get("gender").toString());

            user.setCity(uMap.get("city").toString());
            user.setProvince(uMap.get("province").toString());
            user.setCountry(uMap.get("country").toString());

            if (uMap.containsKey("asmpid")) user.setAsmpid(Long.valueOf(uMap.get("asmpid").toString()));

            if (uMap.containsKey("unionId") && uMap.get("unionId") != null) {
                user.setUnionid(uMap.get("unionId").toString());
            }
            if (uMap.containsKey("openId") && uMap.get("openId") != null) {
                user.setOpenid(uMap.get("openId").toString());
            }
            logger.debug("-------------------------------------------------------------update user=" + JSON.toJSONString(user));

            user.updateById();

            user.setNewuser(false);
        }
        user.setNewguid(newguid);
        if (uMap.containsKey("ori")) process(uMap.get("ori").toString(), user);

        return user;
    }

    private void process(String origin, User user) {
        if (Strings.isNullOrEmpty(origin) || user == null) return;
        if (origin.contains("btn[lingquan]")) {
            String[] oriarr = origin.split("_");//uid_page_act_ywid
            Coupon coupon = new Coupon();
            coupon.setTplid(Long.valueOf(oriarr[3]));
            CouponTpl ctpl = couponTplService.selectById(coupon.getTplid());
            // 不能重复领取
            if (ctpl.getIsRepeat() != 1) {
                Coupon one = couponService.selectOne(new EntityWrapper<Coupon>().eq("tplid", oriarr[3]).eq("uid", user.getId()));
                if (one != null) {
                    return;
                }
            }
            coupon.setIsUnused(1);//未使用
            coupon.setIsUsed(0);//已使用
            coupon.setIsForever(ctpl.getIsForever());//永久有效
            coupon.setIsOutdate(0);//已过期
            coupon.setState(1);

            coupon.setMid(ctpl.getMid());
            coupon.setMpid(ctpl.getMpid());
            coupon.setUid(user.getId());    //领券用户
            coupon.setSid(ctpl.getSid());
            coupon.setCreatetime(new Date());

            coupon.setTplid(ctpl.getId());
            coupon.setType(ctpl.getType());
            coupon.setName(ctpl.getName());
            coupon.setSlogo(ctpl.getSlogo());
            coupon.setSname(ctpl.getSname());
            coupon.setRemark(ctpl.getRemark());

            coupon.setCno(StringUtil.getQuanCode(ObjectUtil.getMid()));

            coupon.setStarttime(DateUtil.getToday());
            coupon.setEndtime(ctpl.getIsForever() == 1 ? null : ctpl.getEndtime());
            coupon.setCost(ctpl.getCost());
            coupon.setUsemin(ctpl.getUsemin());
            coupon.setOriginType(Qgettype.ziling.getVal());//领券来源@1：领取；2：分享；3：赠送&

            coupon.insert();

            ctpl.setUse(ctpl.getUse() + 1);
            ctpl.insertOrUpdate();
        }
    }

    //针对多商户的商户助手小程序登陆接口
    @RequestMapping(value = "/api/user/pmchlogin", method = RequestMethod.POST)
    @ResponseBody
    public Map pmchlogin(@RequestParam("encryptedData") String encryptedData,
                         @RequestParam("iv") String iv,
                         @RequestParam("code") String code,
                         @RequestParam(value = "g", required = false) String guid,
                         @RequestParam(value = "s", required = false) String s,
                         @RequestParam(value = "ud", required = false) String ud,
                         @RequestParam(value = "ori", required = false) String ori
    ) throws Exception {
        //初始化配置文件
        Map map = new HashMap<String, Object>();
        logger.debug("----------------guid=" + guid);
        logger.debug("----------------s=" + s);
        logger.debug("----------------ud=" + ud);
        logger.debug("----------------ori=" + ori);
        logger.info("------------------------------------------------params encryptedData=" + encryptedData);
        logger.info("------------------------------------------------params iv=" + iv);
        logger.info("------------------------------------------------params code=" + code);
        encryptedData = encryptedData.replaceAll(" ", "+");
        logger.debug("-----------------------------------------------wxapplogin after replaceAll encryptedData::" + encryptedData);

        //登录凭证不能为空
        if (code == null || code.length() == 0) {
            map.put("status", 1);
            map.put("msg", "code 不能为空");
            return map;
        }
        Long mid = ObjectUtil.getMid();
        if (mid == null || mid <= 0) {
            map.put("code", 1);
            map.put("msg", "paramter error");
            return map;
        }

        // add redis cache
        MerchantApp mApp = redisService.getMApp();
        logger.info("======user/login mApp=" + mApp);
        if (mApp == null) {
            map.put("code", 2);
            map.put("msg", "未找到商家应用配置");
            return map;
        }

        if (Strings.isNullOrEmpty(mApp.getAppid())) {
            map.put("code", 2);
            map.put("msg", "商家应用还未初始化配置");
            return map;
        }

        // mApp.getAppid() 为非(多门店多分店）商家默认的appid 只有一个
        // ObjectUtil.getAppid() 为多门店多分点商家对应其中某一个的appid
        String appid = mApp.getAppid();
        Long mpid = ObjectUtil.getMpid();
        String secret = mApp.getAppsecret();

        logger.debug("============ori=" + ori);
        map.clear();

        //////////////// 2、对encryptedData加密数据进行AES解密 ////////////////
        try {
            String grant_type = "authorization_code";
            String rskey = Constants.REDIS_SESSION_KEY + mpid + "_" + ObjectUtil.getGuid();
            logger.info("===============wxdectypt rskey=" + rskey);
            String rsessionKey = redisService.get(rskey);
            String sessionKey = rsessionKey;
            String openid = null;
            // 默认使用当前服务器缓存的sessionKey
            logger.info("--------------------------------------no cache and code=" + code);

            if (Strings.isNullOrEmpty(rsessionKey)) {
                //////////////// 1、向微信服务器 使用登录凭证 code 获取 session_key 和 openid ////////////////
                //请求参数
                MerchantApp mapp = redisService.getMApp(mpid);
                String params = "appid=" + appid + "&secret=" + mapp.getAppsecret() + "&js_code=" + code + "&grant_type=" + grant_type;
                logger.info("-------------------------params=" + params);
                //发送请求
                String sr = HttpUtil.sendGet(Constants.WX_URL_JSCODE2SESSION, params);
                logger.debug("--------------------------------------------------sr=" + sr);
                //解析相应内容（转换成json对象）
                JSONObject json = JSONObject.parseObject(sr);
                //获取会话密钥（session_key）
                if (json == null || Strings.isNullOrEmpty(json.getString("session_key"))) {
                    logger.error("sessionKey error for params=" + params);
                    map.put("status", 0);
                    map.put("msg", "解密失败");
                    return map;
                }
                sessionKey = json.getString("session_key");
                openid = json.getString("openid");
            }

            if (Strings.isNullOrEmpty(rsessionKey)) redisService.set(rskey, sessionKey, 7200, TimeUnit.SECONDS);

            logger.info("-------------------------wxdectypt session_key=" + sessionKey);
            if (!Strings.isNullOrEmpty(openid)) {
                User user = userService.selectOne(new EntityWrapper<User>().eq("openid", openid));
                if (user != null) {
                    logger.debug("-------------------------------------------------------------for key user=" + JSON.toJSONString(user));
                    String key = !Strings.isNullOrEmpty(user.getPhone()) && user.getAsmpid() != null ? ObjectUtil.getAsmkey(user) : ObjectUtil.getKey(user, user.getMpid());
                    String token = AesUtil.encrypt(key, Constants.ENCODE_KEY);
                    redisService.set(token, key);

                    map.put("code", 0);
                    map.put("msg", "ok");
                    map.put("guid", user.getGuid());
                    map.put("ismch", user.getIsMch());
                    map.put("islogin", 1);
                    if (!Strings.isNullOrEmpty(user.getPhone()) && user.getAsmpid() != null) {
                        map.put("isphone", 1);
                        map.put("sid", user.getSid());
                        map.put("isAgent", user.getIsAgent() == 1);
                        if (user.getAlevel() != null) map.put("alevel", user.getAlevel());
                    }
                    if (user.getSid() != null) map.put("sid", user.getSid());
                    map.put("token", token);
                    return map;
                }
            }

            String result = AesUtil.decrypt(encryptedData, sessionKey, iv, rskey);
//            JSONObject userInfoJSON = ObjectUtil.wxdectypt(encryptedData, iv, code,map,true);
            JSONObject userInfoJSON = JSON.parseObject(result);
            if (null != userInfoJSON) {
                map.put("code", 0);
                map.put("msg", "ok");

//                JSONObject userInfoJSON = JSONObject.parseObject(result);
                Map userInfo = new HashMap();

                String ip = ObjectUtil.getIP();
//                String location = ObjectUtil.getLocation();
                logger.debug("======ip=" + ip);

                userInfo.put("openId", userInfoJSON.get("openId"));
                userInfo.put("nickName", userInfoJSON.get("nickName"));
                userInfo.put("avatarUrl", userInfoJSON.get("avatarUrl"));
                userInfo.put("gender", userInfoJSON.get("gender"));
                userInfo.put("city", userInfoJSON.get("city"));
                userInfo.put("province", userInfoJSON.get("province"));
                userInfo.put("country", userInfoJSON.get("country"));
                userInfo.put("unionId", userInfoJSON.get("unionId"));
                userInfo.put("appid", appid);
                userInfo.put("appType", ObjectUtil.getAppType());
                userInfo.put("ip", ip);

                if (!Strings.isNullOrEmpty(guid)) userInfo.put("guid", guid);
                if (!Strings.isNullOrEmpty(ud)) userInfo.put("ud", ud);
                userInfo.put("mid", mid);
                userInfo.put("mpid", mpid);

                logger.debug("-------------------------------------------mApp.getAsmpid()=" + mApp.getAsmpid());
                logger.debug("-------------------------------------------mApp.getVersion().intValue()=" + mApp.getVersion().intValue());

                if (mApp.getAsmpid() != null && mApp.getVersion().intValue() == 9)
                    userInfo.put("asmpid", mApp.getAsmpid());

                if (!Strings.isNullOrEmpty(ori)) userInfo.put("ori", ori);

                logger.debug(">>>userInfo=" + userInfo);
                User user = updateUserinfo(userInfo);
                logger.debug(">>>user after updateUserinfo user=" + user);
                if (userInfo.containsKey("updateGuid")) {
                    logger.debug("-------------------------------------------------------------process updateGuid");
                    String rsnewkey = Constants.REDIS_SESSION_KEY + mpid + "_" + user.getGuid();

                    redisService.set(rsnewkey, sessionKey, 7200, TimeUnit.SECONDS);
                    redisService.set(rskey, sessionKey, 7200 - 200, TimeUnit.SECONDS);// 旧缓存默认值，设置过期清除
                }

                userInfo.remove("unionId");

                User muser = userService.selectOne(new EntityWrapper<User>()
                        .setSqlSelect("id,mid,mpid,asmpid,sid,subsid,phone,is_agent isAgent,alevel")
                        .eq("openid", user.getOpenid())); //  ObjectUtil.getUid());
                if (muser == null) {
                    map.put("code", 0);
                    map.put("msg", "用户未登陆请授权登录再重试");
                    return map;
                }

                logger.debug("-------------------------------------------------------------for key muser=" + JSON.toJSONString(muser));
                String key = !Strings.isNullOrEmpty(muser.getPhone()) && muser.getAsmpid() != null ? ObjectUtil.getAsmkey(user) : ObjectUtil.getKey(user, user.getMpid());
                String token = AesUtil.encrypt(key, Constants.ENCODE_KEY);
                redisService.set(token, key);

                map.put("guid", user.getGuid());
                map.put("ismch", user.getIsMch());
                map.put("islogin", 1);
                if (!Strings.isNullOrEmpty(muser.getPhone()) && muser.getAsmpid() != null) {
                    map.put("isphone", 1);
                    map.put("sid", muser.getSid());
                    map.put("isAgent", user.getIsAgent() == 1);
                    if (user.getAlevel() != null) map.put("alevel", user.getAlevel());
                }
                if (muser.getSid() != null) map.put("sid", muser.getSid());
                map.put("token", token);

                return map;
            }
        } catch (Exception e) {
            logger.error("==========encryptedData and process user data error", e);
        }

        map.put("status", 0);
        map.put("msg", "解密失败");
        return map;
    }

    //非匿名绑定手机（登陆状态绑定手机）
    @RequestMapping(value = "/api/user/mchjiemiwx", method = RequestMethod.POST)
    @ResponseBody
    public Jinfo mchjiemiwx(
            @RequestParam("encryptedData") String encryptedData,
            @RequestParam("iv") String iv,
            @RequestParam(value = "g", required = false) String guid,
            @RequestParam("code") String code,
            @RequestParam("t") String t
    ) throws Exception {
        //初始化配置文件
        Jinfo info = new Jinfo();
        logger.info("========================================params encryptedData::" + encryptedData);
        logger.info("========================================params iv=" + iv);
        logger.info("========================================params code=" + code);
        encryptedData = encryptedData.replaceAll(" ", "+");
        logger.debug("--------------------------------------------jiemiwx after replaceAll encryptedData::" + encryptedData);

        //登录凭证不能为空
        if (code == null || code.length() == 0) {
            info.setCode(1);
            info.setMsg("paramter error");
            return info;
        }
        Long mainmpid = ObjectUtil.getMainmpid();
        MerchantApp mApp = redisService.getMApp(mainmpid);

//        String appid = ObjectUtil.getAppid();
//        Long mpid = ObjectUtil.getMpid();
        String appid = mApp.getAppid();
        String secret = mApp.getAppsecret();

        logger.info("===============secret=" + secret);
        //授权（必填）
        String grant_type = "authorization_code";
        String rskey = Constants.REDIS_SESSION_KEY + mainmpid + "_" + ObjectUtil.getGuid();
        String rsessionKey = redisService.get(rskey);
        String sessionKey = rsessionKey;
        String unionid = null;
        if (Strings.isNullOrEmpty(rsessionKey)) {
            String params = "appid=" + appid + "&secret=" + secret + "&js_code=" + code + "&grant_type=" + grant_type;
            logger.info("===============params=" + params);
            //发送请求
            String sr = HttpUtil.sendGet(Constants.WX_URL_JSCODE2SESSION, params);
            logger.debug(">>>>>>>>>>>>>>>>>>>>>>>sr=" + sr);
            //解析相应内容（转换成json对象）
            JSONObject json = JSONObject.parseObject(sr);
            //获取会话密钥（session_key）
            sessionKey = json.get("session_key").toString();

            if (json.containsKey("unionid")) unionid = json.get("unionid").toString();
            if (Strings.isNullOrEmpty(sessionKey)) {
                info.setCode(1);
                info.setMsg("sessionKey error");
                return info;
            }
        }
        if (Strings.isNullOrEmpty(rsessionKey)) {
            redisService.set(rskey, sessionKey, 7200, TimeUnit.SECONDS);
        }

        logger.info("===============session_key=" + sessionKey);
        //////////////// 2、对encryptedData加密数据进行AES解密 ////////////////
        try {
            String result = AesUtil.decrypt(encryptedData, sessionKey, iv, rskey);

            if (null != result && result.length() > 0) {
                logger.info("===============result=" + result);
                JSONObject jo = JSONObject.parseObject(result);

                User nuser = new User();

                if (jo.containsKey("phoneNumber") && ObjectUtil.getUid() != null) {

                    if (ObjectUtil.getUid() != null) nuser.setId(ObjectUtil.getUid());
                    if (!Strings.isNullOrEmpty(guid)) nuser.setGuid(guid);
                    if (!Strings.isNullOrEmpty(unionid)) nuser.setUnionid(unionid);

                    nuser.setPhone(jo.getString("phoneNumber"));
                    nuser.insertOrUpdate();

                    // 更新用户缓存信息
                    redisService.delUser();
                } else {
                    info.setCode(1);
                    info.setMsg("绑定手机失败，请重试");
                    return info;
                }

                User muser = userService.selectOne(new EntityWrapper<User>()
                        .setSqlSelect("id,mid,mpid,asmpid,sid,subsid,phone,is_agent isAgent,alevel")
                        .eq("id", ObjectUtil.getUid())); //  ObjectUtil.getUid());
                if (muser == null) {
                    info.setCode(1);
                    info.setMsg("用户未登陆请授权登录再重试");
                    return info;
                }

                String key = ObjectUtil.getAsmkey(muser);
                String token = AesUtil.encrypt(key, Constants.ENCODE_KEY);
                redisService.del(t);
                redisService.set(token, key);
                logger.info("========jiemiwx token=" + token);
                logger.info("========jiemiwx key=" + key);
                info.setToken(token);
                info.setIsphone(1);
                info.setSid(muser.getSid());
                info.setAgent(muser.getIsAgent() == 1);

                info.setInfo(jo);
                return info;
            } else {
                info.setCode(1);
                info.setMsg("parse and decrypt error");
            }
        } catch (Exception e) {
            logger.error("======jiemiwx error", e);
            info.setCode(1);
        }

        return info;
    }

    // =========== below for gongzhonghao ==========

    @RequestMapping(value = "/wx/{mpid}/api", method = RequestMethod.GET, produces = "text/plain;charset=utf-8")
    @ResponseBody
    public void connect(WeChat wc, @PathVariable String mpid, HttpServletResponse rsp) {
        String signature = wc.getSignature(); // 微信加密签名
        String timestamp = wc.getTimestamp(); // 时间戳
        String nonce = wc.getNonce();// 随机数
        String echostr = wc.getEchostr();// 随机字符串
        HttpSession s = ObjectUtil.getSession();
        s.setAttribute("mpid", mpid);

        // 通过检验signature对请求进行校验，若校验成功则原样返回echostr，表示接入成功，否则接入失败
        if (SignUtil.checkSignature(signature, timestamp, nonce, mpid)) {
            logger.debug("========return echostr=" + echostr);
        } else {
            logger.warn("不是微信服务器发来的请求,请小心!");
            echostr = "不是微信服务器发来的请求,请小心!";
        }

        try {
            BufferedOutputStream out = new BufferedOutputStream(rsp.getOutputStream());
            out.write(echostr.getBytes());
            out.flush();
            out.close();
        } catch (Exception e) {
            logger.error("======wx connect error", e);
        }
    }

    @RequestMapping(value = "/wx/{mpid}/api", method = RequestMethod.POST)
    @ResponseBody
    public String getWeiXinMessage(HttpServletRequest request, @PathVariable String mpid) throws Exception {
        //初始化配置文件
        HttpSession s = ObjectUtil.getSession();
        s.setAttribute("mpid", mpid);
        String respMessage = weixinService.processRequest(request, mpid);//调用CoreService类的processRequest方法接收、处理消息，并得到处理结果；

        // 响应消息
        //调用response.getWriter().write()方法将消息的处理结果返回给用户
        return respMessage;
    }

    @RequestMapping(value = "/wx/{mpid}/oauth2", method = RequestMethod.GET)
    @ResponseBody
    public String oauth2(HttpServletRequest request, @PathVariable String wxType) throws Exception {
        //初始化配置文件
        String respMessage = weixinService.processRequest(request, wxType);//调用CoreService类的processRequest方法接收、处理消息，并得到处理结果；

        // 响应消息
        //调用response.getWriter().write()方法将消息的处理结果返回给用户
        return respMessage;
    }

    //小程序消息通讯服务
    @RequestMapping(value = "/mapp/{mpid}/api", method = RequestMethod.GET, produces = "text/plain;charset=utf-8")
    @ResponseBody
    public void mappconnect(WeChat wc, @PathVariable String mpid, HttpServletResponse rsp) {
        logger.debug("==========================mapp/" + mpid + "/api POST");

        String signature = wc.getSignature(); // 微信加密签名
        String timestamp = wc.getTimestamp(); // 时间戳
        String nonce = wc.getNonce();// 随机数
        String echostr = wc.getEchostr();// 随机字符串
        HttpSession s = ObjectUtil.getSession();
        s.setAttribute("mpid", mpid);

        // 通过检验signature对请求进行校验，若校验成功则原样返回echostr，表示接入成功，否则接入失败
        if (SignUtil.checkSignature(signature, timestamp, nonce, mpid)) {
            logger.debug("========return echostr=" + echostr);
        } else {
            logger.warn("不是微信服务器发来的请求,请小心!");
            echostr = "不是微信服务器发来的请求,请小心!";
        }

        try {
            BufferedOutputStream out = new BufferedOutputStream(rsp.getOutputStream());
            out.write(echostr.getBytes());
            out.flush();
            out.close();
        } catch (Exception e) {
            logger.error("======wx connect error", e);
        }
    }

    //小程序消息通讯服务
    @RequestMapping(value = "/mapp/{mpid}/api", method = RequestMethod.POST)
    @ResponseBody
    public void getMappMessage(HttpServletRequest request,
                               @PathVariable String mpid,
                               HttpServletResponse rsp) throws Exception {
        logger.debug("==========================mapp/" + mpid + "/api POST");

        //初始化配置文件
        HttpSession s = ObjectUtil.getSession();
        s.setAttribute("mpid", mpid);
        rsp.setContentType("text/xml");

        String respMessage = "success";
        MerchantApp mapp = redisService.getMApp(Long.valueOf(mpid));
        if (mapp.getAppType() == 2) {
            //小程序
            respMessage = weixinService.processMiniappRequest(request, mpid);
            if (!Strings.isNullOrEmpty(respMessage) && respMessage.contains("<CreateTime>")) {
                respMessage = respMessage.replace("<CreateTime><![CDATA[", "<CreateTime>");
                respMessage = respMessage.replace("]]></CreateTime>", "</CreateTime>");
            }
            logger.debug("==========================mapp/" + mpid + "/api miniapp respMessage=" + respMessage);
//            return respMessage;
        } else {
            // 响应消息
            respMessage = weixinService.processRequest(request, mpid);//调用CoreService类的processRequest方法接收、处理消息，并得到处理结果；
            logger.debug("==========================mapp/" + mpid + "/api gzh respMessage=" + respMessage);
            //调用response.getWriter().write()方法将消息的处理结果返回给用户
//            return respMessage;
        }
        if (respMessage == null) respMessage = "";
        try {
            BufferedOutputStream out = new BufferedOutputStream(rsp.getOutputStream());
            out.write(respMessage.getBytes());
            out.flush();
            out.close();
        } catch (Exception e) {
            logger.error("==========================mapp/" + mpid + "/api miniapp error", e);
        }
    }

}
